package weixin

import (
	"encoding/xml"
	"github.com/astaxie/beego/logs"
	"time"
)

const (
	BAD_REQUEST         = -400
	TOKEN               = "abcdefg"
	APPID               = "wxe4ecaba4be6415c1"
	APPSECRET           = "ff1d055d56aa0ee573eb776fde31a1a8"
	ACCESSTOKENFETCHURL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + APPID + "&secret=" + APPSECRET
	WX_VOICE               = "voice"       //语音
	WX_SHORTVIDEO          = "shortvideo"  //小视频
	WX_LOCATION            = "location"    //地理位置
	WX_LINK                = "link"        //链接消息
	WX_VIDEO               = "video"       //视频消息
	WX_IMAGE               = "image"       //图片
	WX_NEWS             = "news"        //回复图文消息
	WX_TEXT             = "text"        //文本
	WX_WEIXIN_EVENT        = "event"       //事件
	WX_SUBSCRIBE           = "subscribe"   //订阅
	WX_UNSUBSCRIBE         = "unsubscribe" //取消订阅
	WX_SCAN                = "SCAN"
)

type CDATA string

func (c CDATA) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
	return e.EncodeElement(struct {
		string `xml:",cdata"`
	}{string(c)}, start)
}

type WeiXinMsg struct {
	XMLName      xml.Name `xml:"xml"`                //
	ToUserName   CDATA   `xml:",omitempty," `        //开发者微信号
	FromUserName CDATA    `xml:",omitempty," `       //发送方帐号（一个OpenID）
	CreateTime   time.Duration  `xml:",omitempty," ` //消息创建时间 （整型）
	MsgType      CDATA    `xml:",omitempty," `       //消息类型
	Content      CDATA    `xml:",omitempty," `       //文本消息内容
	PicUrl       CDATA    `xml:",omitempty," `       //图片链接（由系统生成）
	MediaId      CDATA    `xml:",omitempty," `       //语音消息媒体id，可以调用多媒体文件下载接口拉取该媒体
	Format       CDATA   `xml:",omitempty," `        //语音格式：amr
	Recognition  CDATA    `xml:",omitempty," `       //语音识别结果，UTF8编码
	ThumbMediaId CDATA    `xml:",omitempty," `       //视频消息缩略图的媒体id，可以调用多媒体文件下载接口拉取数据。
	MsgId        int64     `xml:",omitempty," `      //消息id，64位整型
	Location_X   float64   `xml:",omitempty," `      //地理位置维度
	Location_Y   float64  `xml:",omitempty," `       //地理位置经度
	Scale        int       `xml:",omitempty," `      //地图缩放大小
	Label        CDATA    `xml:",omitempty," `       //地理位置信息
	Title        CDATA    `xml:",omitempty," `       //消息标题
	Description  CDATA    `xml:",omitempty," `       //消息描述
	Url          CDATA    `xml:",omitempty," `       //消息链接
	Event        CDATA    `xml:",omitempty," `       //事件类型
	EventKey     CDATA    `xml:",omitempty," `       //事件KEY值，qrscene_为前缀，后面为二维码的参数值
	Ticket       CDATA    `xml:",omitempty," `       //二维码的ticket，可用来换取二维码图片
	ArticleCount int `xml:",omitempty,"`             //图文消息个数，限制为8条以内
	Articles     *Articles  `xml:",omitempty,"`      //图文消息
}

type Item struct {
	Title       CDATA `xml:"Title,omitempty"`
	Description CDATA `xml:"Description,omitempty"`
	PicUrl      CDATA `xml:"PicUrl,omitempty"`
	Url         CDATA `xml:"Url,omitempty"`
}
type Articles struct {
	Item []Item `xml:"item,omitempty,"`
}

type WeiXinError struct {
	Errcode int64 `json:"errcode"` //错误码
	Errmsg  string `json:"errmsg"` //错误信息
}

func NewWeiXinError() *WeiXinError {
	return &WeiXinError{BAD_REQUEST, "请求失败"}
}

func (this *WeiXinMsg) replay() (txtMsg *WeiXinMsg) {
	txtMsg = &WeiXinMsg{}
	txtMsg.CreateTime = time.Duration(time.Now().Unix())
	txtMsg.ToUserName = this.FromUserName
	txtMsg.FromUserName = this.ToUserName
	return
}

func (this *WeiXinMsg) ReplayText(content CDATA) (txtMsg *WeiXinMsg) {
	txtMsg = this.replay()
	txtMsg.MsgType = WX_TEXT
	txtMsg.Content = content
	return
}

func (this *WeiXinMsg) ReplayNews() (newsMsg *WeiXinMsg) {
	newsMsg = this.replay()
	newsMsg.MsgType = WX_NEWS
	newsMsg.Articles = &Articles{}
	return
}

func (this *WeiXinMsg) AppendNews(title, description, picUrl, url CDATA) {
	logs.Debug("增加图文: title:%s,description:%s, picUrl:%s, url:%s", title, description, picUrl, url)
	//图文消息个数，限制为8条以内
	if this.ArticleCount > 8 {
		return
	}
	this.ArticleCount++
	this.Articles.Item = append(this.Articles.Item, Item{Title: title, Description: description, PicUrl: picUrl, Url: url})

}

func Xml2WeiXin(input []byte) (msg *WeiXinMsg) {
	logs.Debug("来自微信消息:%s", input)
	err := xml.Unmarshal(input, &msg)
	if err != nil {
		logs.Error("解析xml失败：%s", err, input)
		return nil
	}
	return
}

func (this *WeiXinMsg) ToXml() string {
	output, err := xml.MarshalIndent(this, " ", " ")
	if err != nil {
		logs.Error("转换xml失败：%s", err)
		return ""
	}
	logs.Debug("回复微信消息:%s", string(output))
	return string(output)
}
